Distributive Conditional Types
Distributive Union
Conditional TypesのT extends U ? X : Yの内、
Tがunion型 (ts)の時、簡約時に分配される
例えば、Tが、A|B|Cだとすると、
直感的には、(A|B|C extends U) ? X : Yになりそうだが、
実際は、(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)になる
以下のことにも注意
[U] extends ..でdistributeを避ける
T がneverの時の、T extends .. は、問答無用でneverになる
docs
例えば、Exclude<U, E>
Exclude<U, E>はこんな定義だった
code:ts
type Exclude<T, U> = T extends U ? never : T;
ここで、第1引数、第2引数に下記を使うことを考える
code:ts
type T1 = 'a' | 'b' | 'c';
type U1 = 'a' | 'b';
分配されることを無視して、そのままExclude<U, E>の定義に代入すると、こうなる
code:ts
type A = T1 extends U1 ? never : T1; // 'a' | 'b' | 'c'
実際に、Exclude<U, E>を適用した場合は以下なので結果が異なる
code:ts
type B = Exclude<T1, U1>; // 'c'
これは、Exclude<U, E>が以下のように分配して簡約されるからである
code:ts
type B = Exclude<T1, U1>;
// T1を代入
= Exclude<'a' | 'b' | 'c', U1>;
// 分配!
= Exclude<'a', U1> | Exclude<'b', U1> | Exclude<'c', U1>;
// 個々で結果が得られる
= never | never | 'c';
// 結果
= 'c';